#include "freyacommanddistribution.h"
#include "freyabasecontrol.h"
#include "freyabaseaction.h"

FreyaCommandDistribution::FreyaCommandDistribution(FreyaBaseControl *pControl) :
    QThread(nullptr), m_pControl(pControl)
{
    setObjectName("CMDDistribution");
}

bool FreyaCommandDistribution::InsertData(FreyaData pData)
{
    QMutexLocker locker(&m_QueueMutex);

    if(BD_Priority_Hig == pData->GetProperty(FREYALIB_FLG_PRIORITY).toInt())
    {
        qDebug() << "FreyaLib >" << "High priority FreyaData: DataID:" << pData->dataID
                 << "Command:" << m_pControl->CmdLogString(pData->command);
        m_DataQueue.insert(0, pData);
    }
    else
    {
        m_DataQueue.append(pData);
    }
    m_TaskSem.release();
    return true;
}

bool FreyaCommandDistribution::HasData()
{
    QMutexLocker locker(&m_QueueMutex);
    return (!m_DataQueue.isEmpty());
}

FreyaData FreyaCommandDistribution::TakeData()
{
    QMutexLocker locker(&m_QueueMutex);
    return m_DataQueue.takeFirst();
}

void FreyaCommandDistribution::run()
{
    while(true)
    {
        m_TaskSem.acquire();
        if(!HasData())
        {
            continue;
        }
        FreyaData pData = TakeData();

        m_pControl->m_pRequester = VARIANTTOCUSTOMCLS(pData->GetProperty(FREYALIB_FLG_REQUESTER), void);
//        FreyaBaseAction *reqAction = static_cast<FreyaBaseAction*>(pRequester);

        qDebug() << "FreyaLib > " << "Execution: DataID:" << pData->dataID
                 << "Command:" << m_pControl->CmdLogString(pData->command)
                 << "From:" << m_pControl->m_pRequester;
        QHashIterator<FreyaBaseAction*, QString> ActionIt(m_pControl->m_FreyaPublicRegister.AllRegisterAction());
        while (ActionIt.hasNext())
        {
            ActionIt.next();
            FreyaBaseAction *pAction = ActionIt.key();
            if(m_pControl->m_FreyaPublicRegister.CheckObjectCommand(pAction, pData->command))
            {
//                if(!(reqAction && reqAction == pAction))
                {
//                    QMetaObject::invokeMethod(m_pControl, "ActionExecution", Qt::QueuedConnection, Q_ARG(FreyaBaseAction*, pAction), Q_ARG(FreyaData, pData));
                    pAction->ExecuteCache(pData);
                }
            }
        }
//        m_pControl->m_pRequester = NULL;
    }
}
